﻿using Hangout.Web.Core.Meetup;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Hangout.Web.Services.Meetup
{
    public class Meetup
    {
         Web.Model.HangoutDBEntities context = new Web.Model.HangoutDBEntities();



        public  void InsertHangout(int userId, bool moderateHangoutRequest, string description, string text, Web.Model.Location screenshotLocation, Web.Model.Location location, DateTime hangoutdateTime, DateTime clientDateTime, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userId, accesstoken, context))
                {
                    Web.Model.Hangouts hangout = Web.Core.Meetup.Meetup.InsertHangout(userId, moderateHangoutRequest, description, text, screenshotLocation, location,  hangoutdateTime, clientDateTime, ref context);
                    Web.Core.Score.UserScore.IncreaseUserScore(userId, 8, ref context); //Increase the user score to 8
                    Web.Core.Meetup.Meetup.JoinHangout(userId, hangout.HangoutID, clientDateTime, ref context); //join in hangout :)
                    Web.Core.Meetup.Meetup.AddHangoutComment(userId, hangout.HangoutID, " created this Hangout", clientDateTime, ref context);//add a hangout comment
                    Web.Core.Tokens.Tokens.IncreaseTokenScore(Web.Core.Text.TextManipulation.GetAllTokens(text), 6, userId, ref context); //increase token score by 6
                    //send a notification to those compatible
                    Core.Cloud.Queue.AddCloudHangoutInsertedMessage(userId, hangout.HangoutID);
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);

            }


        }




        public  Services.Objects.Meetup GetLastHangout(int userId)
        {
            try
            {
                
                    Web.Model.Hangouts hangout = Web.Core.Meetup.Meetup.GetLastHangout(userId, ref context);

                    if (hangout == null)
                    {
                        return null;
                    }

                    return new Services.Objects.Meetup { StatusText = hangout.StatusText, HangoutID = hangout.HangoutID, User = new Objects.User{UserID= hangout.UserID}, DateTimePosted = hangout.DateTimeStamp }; //a light service object returned. 
                
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return null;
            }
        }


        public  List<Services.Objects.Meetup> GetUserLatestHangouts(int userId, int skip, int take)
        {
            try
            {
                
                    List<Web.Model.Hangouts> hangouts= Web.Core.Meetup.Meetup.GetUserLatestHangouts(userId, skip, take, ref context);
                    return hangouts.Select(o => new Services.Objects.Meetup { StatusText = o.StatusText, HangoutID = o.HangoutID, User = new Objects.User{UserID= o.UserID}, DateTimePosted = o.DateTimeStamp }).ToList();
                
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return null;
            }
        }

        public  Objects.MeetupData GetHangout(int hangoutId, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(accesstoken, context))
                {
                    Web.Model.Hangouts data = Web.Core.Meetup.Meetup.GetHangout(hangoutId, ref context);

                    return new Objects.MeetupData { Description = data.Description, Hangout = new Objects.Meetup { DateTimePosted = data.DateTimeStamp, HangoutDateTime = (DateTime)data.HangoutDateTime, HangoutID = data.HangoutID, StatusText = data.StatusText, User = new Objects.User { UserID = data.UserID } }, Location = new Objects.Location { Address = data.Location1.FormattedAddress, City = data.Location1.Locality, Country = data.Location1.CountryRegion, Latitude = data.Location1.Latitude, Longitude = data.Location1.Longitude, LocationID = data.Location.LocationID } };
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(0, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return null;
            }
        }

        public  List<Services.Objects.User> GetUsersInHangout(int hangoutId, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(accesstoken, context))
                {
                    return Web.Core.Meetup.Meetup.GetUsersInHangout(hangoutId, ref context).Select(o=>new Services.Objects.User{Name=o.Name,ProfilePicURL=o.ProfilePicURL,Status=o.Bio,UserID=o.UserID}).ToList();
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(0, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return null;
            }
        }

        public  List<Services.Objects.HangoutComment> GetHangoutComments(int hangoutId, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(accesstoken, context))
                {
                    return Web.Core.Meetup.Meetup.GetHangoutComments(hangoutId, ref context).Select(o=>new Services.Objects.HangoutComment{Comment=o.comment.CommentText,DatePosted=o.comment.DateTimeStamp,User=new Objects.User{Name=o.profile.Name,ProfilePicURL=o.profile.ProfilePicURL,UserID=o.profile.UserID}}).ToList();
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(0, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return null;
            }
        }

        public  List<Services.Objects.HangoutComment> GetHangoutCommentsAfter(int hangoutId, DateTime after, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(accesstoken, context))
                {
                    return Web.Core.Meetup.Meetup.GetHangoutCommentsAfter(hangoutId, after, ref context).Select(o => new Services.Objects.HangoutComment { Comment = o.comment.CommentText, DatePosted = o.comment.DateTimeStamp, User = new Objects.User { Name = o.profile.Name, ProfilePicURL = o.profile.ProfilePicURL, UserID = o.profile.UserID } }).ToList(); ;
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(0, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return null;
            }
        }


        public  void AddHangoutComment(int userId, int hangoutId, string text, DateTime clientdatetime, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userId, accesstoken, context))
                {
                    Web.Core.Meetup.Meetup.AddHangoutComment(userId, hangoutId, text, clientdatetime, ref context);
                    //get users in Hangout
                    List<int> userids = Web.Core.Meetup.Meetup.GetUsersInHangout(hangoutId, ref context).Select(o => o.UserID).ToList();
                    if (userids.Contains(userId))
                    {
                        userids.Remove(userId);
                    }
                    //send notification
                    Web.Core.Notifications.Notification.AddNotification(userids, "commented " + text.Substring(0, Math.Min(20, text.Length - 1)) + "... on a Hangout you're joined in.", "Hangout:" + hangoutId, ref context);
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }

            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);
            }

        }

        public  bool IsPinned(int userId, int hangoutId, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userId, accesstoken, context))
                {
                    return Web.Core.Meetup.Meetup.IsPinned(userId, hangoutId, context);
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }


            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return false;
            }

        }

        public  List<Services.Objects.Meetup> GetAllPinned(int userId, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userId, accesstoken, context))
                {
                    return Web.Core.Meetup.Meetup.GetAllPinned(userId, ref context).Select(o=>new Services.Objects.Meetup{DateTimePosted=o.Hangout.DateTimeStamp,HangoutID=o.Hangout.HangoutID,IsPinned=o.Pinned,StatusText=o.Hangout.StatusText,User=new Objects.User{Name=o.Profile.Name,ProfilePicURL=o.Profile.ProfilePicURL,UserID=o.Profile.UserID}}).ToList();
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return null;
            }
        }

        public  void PinHangout(int userId, int hangoutId, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userId, accesstoken, context))
                {
                    Web.Core.Meetup.Meetup.PinHangout(userId, hangoutId, ref context);
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);

            }
        }

        public  void UnPinHangout(int userId, int hangoutId, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userId, accesstoken, context))
                {
                    Web.Core.Meetup.Meetup.UnPinHangout(userId, hangoutId, ref context);
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);

            }

        }

        public  bool JoinedInHangout(int userId, int hangoutId, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userId, accesstoken, context))
                {
                    return Web.Core.Meetup.Meetup.JoinedInHangout(userId, hangoutId, ref context);
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return false;
            }
        }

        public  Web.Core.Meetup.CheckInStatus CheckIn(int userId, int hangoutId, DateTime clientDateTime, double latitude, double longitude, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userId, accesstoken, context))
                {
                    Web.Core.Meetup.CheckInStatus status = Web.Core.Meetup.Meetup.CheckIn(userId, hangoutId, latitude, longitude, clientDateTime, ref context);
                    if (status == CheckInStatus.Success)
                    {
                        //increase score;
                        Web.Core.Score.UserScore.IncreaseUserScore(userId, 7, ref context); //Increase the user score to 7
                        Web.Core.Meetup.Meetup.AddHangoutComment(userId, hangoutId, " checked-in.", clientDateTime, ref context);//add a hangout comment
                        Web.Core.Tokens.Tokens.IncreaseTokenScore(Web.Core.Text.TextManipulation.GetAllTokens(Web.Core.Meetup.Meetup.GetHangout(hangoutId, ref context).StatusText), 5, userId, ref context); //increase token score by 5
                        //check for trophies;
                        Core.Cloud.Queue.AddTrophyRefreshTextToCloudQueue(userId); //add text to worker role and this will be later decoded. :)
                        //send notifications to all the users
                        List<int> userids = Web.Core.Meetup.Meetup.GetUsersInHangout(hangoutId, ref context).Select(o => o.UserID).ToList();
                        if (userids.Contains(userId))
                        {
                            userids.Remove(userId);
                        }
                        //send notification
                        Web.Core.Notifications.Notification.AddNotification(userids, Web.Core.Accounts.User.GetUserProfile(userId, context).Name + " checked in to a Hangout.", "Hangout:" + hangoutId, ref context);

                    }

                    return status;
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return CheckInStatus.Error;

            }
        }

        public  void JoinHangout(int userId, int hangoutId, DateTime clientDateTime, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userId, accesstoken, context))
                {
                    Web.Core.Meetup.Meetup.JoinHangout(userId, hangoutId, clientDateTime, ref context);
                    Web.Core.Meetup.Meetup.AddHangoutComment(userId, hangoutId, " Joined this hangout", clientDateTime, ref context);
                    Web.Core.Score.UserScore.IncreaseUserScore(userId, 1, ref context); //Increase the user score to 1
                    Web.Core.Tokens.Tokens.IncreaseTokenScore(Web.Core.Text.TextManipulation.GetAllTokens(Web.Core.Meetup.Meetup.GetHangout(hangoutId, ref context).StatusText), 2, userId, ref context); //increase token score by 2
                    List<int> userids = Web.Core.Meetup.Meetup.GetUsersInHangout(hangoutId, ref context).Select(o => o.UserID).ToList();
                    if (userids.Contains(userId))
                    {
                        userids.Remove(userId);
                    }
                    //send notification
                    Web.Core.Notifications.Notification.AddNotification(userids, Web.Core.Accounts.User.GetUserProfile(userId, context).Name + " joined a Hangout you're joined in.", "Hangout:" + hangoutId, ref context);
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);

            }
        }

        public  void UnJoinHangout(int userId, int hangoutId, DateTime clientdatetime, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userId, accesstoken, context))
                {
                    Web.Core.Meetup.Meetup.UnJoinHangout(userId, hangoutId, clientdatetime, ref context);
                    Web.Core.Meetup.Meetup.AddHangoutComment(userId, hangoutId, " left this hangout", clientdatetime, ref context);
                    Web.Core.Score.UserScore.DecreaseUserScore(userId, 1, ref context); //Increase the user score to 8
                    List<int> userids = Web.Core.Meetup.Meetup.GetUsersInHangout(hangoutId, ref context).Select(o => o.UserID).ToList();
                    if (userids.Contains(userId))
                    {
                        userids.Remove(userId);
                    }
                    //send notification
                    Web.Core.Notifications.Notification.AddNotification(userids, Web.Core.Accounts.User.GetUserProfile(userId, context).Name + " left a Hangout", "Hangout:" + hangoutId, ref context);
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);

            }


        }


        public  bool IsCheckedIn(int userId, int hangoutId, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userId, accesstoken, context))
                {
                    return Web.Core.Meetup.Meetup.IsCheckedIn(userId, hangoutId, ref context);
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return false;
            }
        }


        public  bool CanCheckIn(int userId, int hangoutid, string accesstoken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userId, accesstoken, context))
                {
                    return Web.Core.Meetup.Meetup.CanCheckIn(userId, hangoutid, ref context);
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return false;

            }
        }


        public  List<Services.Objects.Meetup> GetUserHangout(int userId, int take, int skip)
        {
            try
            {
                
                    return Web.Core.Meetup.Meetup.GetUserHangout(userId, take, skip, context).Select(o => new Services.Objects.Meetup { DateTimePosted = o.Hangout.DateTimeStamp, HangoutID = o.Hangout.HangoutID, IsPinned = o.Pinned, StatusText = o.Hangout.StatusText, User = new Objects.User { Name = o.Profile.Name, ProfilePicURL = o.Profile.ProfilePicURL, UserID = o.Profile.UserID } }).ToList(); ;
               
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userId, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return null;
            }
        }

        public  List<Services.Objects.Meetup> GetLatestHangouts(int userid, int take, int skip, string accessToken)
        {
            try
            {

                if (Web.Core.Accounts.User.IsValid(userid, accessToken, context))
                {
                    return Web.Core.Meetup.Meetup.GetLatestHangouts(userid, take, skip, context).Select(o => new Services.Objects.Meetup { DateTimePosted = o.Hangout.DateTimeStamp, HangoutID = o.Hangout.HangoutID, IsPinned = o.Pinned, StatusText = o.Hangout.StatusText, User = new Objects.User { Name = o.Profile.Name, ProfilePicURL = o.Profile.ProfilePicURL, UserID = o.Profile.UserID } }).ToList(); ;
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userid, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return null;

            }
        }

        public  List<Services.Objects.Meetup> SearchHangouts(int userid, string text, int take, int skip, string accessToken)
        {
            try
            {
                if (Web.Core.Accounts.User.IsValid(userid, accessToken, context))
                {
                    return Web.Core.Meetup.Meetup.SearchHangouts(userid, text, take, skip, context).Select(o => new Services.Objects.Meetup { DateTimePosted = o.Hangout.DateTimeStamp, HangoutID = o.Hangout.HangoutID, IsPinned = o.Pinned, StatusText = o.Hangout.StatusText, User = new Objects.User { Name = o.Profile.Name, ProfilePicURL = o.Profile.ProfilePicURL, UserID = o.Profile.UserID } }).ToList(); ;
                }
                else { throw new Web.Core.Exceptions.Account.UnAuthorisedAccess(); }
            }
            catch (System.Exception ex)
            {
                Web.Core.Exceptions.ExceptionReporting.AddAnException(userid, Web.Core.ClientType.WindowsAzure, ex, ref context);
                return null;
            }
        }
    }
}